/*******************************************************************************
 * Copyright (c) Emil Crumhorn - Hexapixel.com - emil.crumhorn@gmail.com
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    emil.crumhorn@gmail.com - initial API and implementation
 *******************************************************************************/ 

package com.hexapixel.widgets.generic;

import java.io.IOException;
import java.io.InputStream;

import org.eclipse.jface.resource.DeviceResourceException;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.ImageRegistry;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.resource.ResourceManager;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Display;

public class ImageCache {

    private static final String PATH = "";

    private static final ResourceManager rm = JFaceResources.getResources(Display.getDefault());
    private static final ImageRegistry idRegistry = new ImageRegistry(rm);
    private static final ImageRegistry imRegistry = new ImageRegistry(rm);

    /**
     * Returns an image that is also cached if it has to be created and does not already exist in the cache.
     * 
     * @param fileName Filename of image to fetch
     * @return Image file or null if it could not be found
     */
    public static Image getImage(String fileName) {
        Image image = imRegistry.get(fileName);
        if (image == null) {
            ImageDescriptor id = createImage(fileName);
            try {
                image = rm.createImage(id);
            } catch (DeviceResourceException e) {
                e.printStackTrace();
            }
            imRegistry.put(fileName, image);
            idRegistry.put(fileName, id);
        }
        return image;
    }

    /**
     * Returns an ImageDescriptor that is also cached if it has to be created and does not already exist in the cache.
     * 
     * @param fileName Filename of image to fetch
     * @return ImageDescriptor or null if it could not be found
     */
    public static ImageDescriptor getImageDescriptor(String fileName) {
        ImageDescriptor id = idRegistry.getDescriptor(fileName);
        if (id == null) {
            ImageDescriptor image = createImage(fileName);
            idRegistry.put(fileName, image);
            Image im;
            try {
                im = rm.createImage(image);
                imRegistry.put(fileName, im);
            } catch (DeviceResourceException e) {
                e.printStackTrace();
            }
            return image;
        }

        return id;
    }

    private static ImageDescriptor createImage(String fileName) {
        // try getting branded image, if no image, get normal image
        String path = PATH + fileName;

        ClassLoader classLoader = ImageCache.class.getClassLoader();
        InputStream is = classLoader.getResourceAsStream(path);
        if (is == null) {
            // the old way didn't have leading slash, so if we can't find the image stream,
            // let's see if the old way works.
            is = classLoader.getResourceAsStream(path.substring(1));

            if (is == null) {
                is = classLoader.getResourceAsStream(path);
                if (is == null) {
                    is = classLoader.getResourceAsStream(path.substring(1));
                    if (is == null) {
                        //logger.debug("null input stream for both " + path + " and " + path);
                        return null;
                    }
                }
            }
        }

        Image img = new Image(Display.getDefault(), is);
        try {
            is.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return ImageDescriptor.createFromImage(img);
    }

    /**
     * Disposes ALL images that have been cached, Images AND ImageDescriptors.
     * <p>
     * <b>IMPORTANT: ONLY CALL WHEN YOU WANT TO DISPOSE ALL CACHED IMAGES!</b>
     *
     */
    public static void dispose() {
        imRegistry.dispose();
        idRegistry.dispose();
    }
}
